package com.tbit.uqbike.client.remote.paypal;


import com.paypal.http.HttpResponse;
import com.paypal.orders.Order;
import com.paypal.orders.OrdersGetRequest;
import com.paypal.payments.CapturesRefundRequest;
import com.paypal.payments.Money;
import com.paypal.payments.Refund;
import com.paypal.payments.RefundRequest;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * @Author: chen
 * @Description:
 * @Date: 创建于 10:33 2021/4/28
 */
@Slf4j
public class RefundOrder extends PayPalClient {


    private String clientId = "AfQGD3ym878GHQVA_xBPiXPNTNP_54C-IGhTgw193wd7t3nNKd6f9ekVvvvAEjtbEYcnmQYZD5ER4y-k";
    private String clientSecret = "EAmRYJfb6fuQ0UCFjKIuJipcnG2A5oq4-PKlN4TLYb8Jp4C5P5c2EbM7TyoMX3f5FLX28Bn5sHBcBdLF";
    private String mode = "sandbox";

    public static void main(String[] args) {
        RefundOrder refundOrder = new RefundOrder();
        try {
            refundOrder.refundOrder(refundOrder.mode, refundOrder.clientId, refundOrder.clientSecret, "8BV96888K13076357", 5.00, "3123");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }

    /**
     * 创建退款请求体
     */
    public RefundRequest buildRequestBody(double refundMoney, String orderNO) {
        RefundRequest refundRequest = new RefundRequest();
        Money money = new Money();
        money.currencyCode("USD");
        money.value(String.valueOf(refundMoney));
        refundRequest.amount(money);
        refundRequest.invoiceId(orderNO);
        refundRequest.noteToPayer("退款");
        return refundRequest;
    }

    /**
     * 申请退款
     */
    public Boolean refundOrder(String mode, String clientId, String clientSecret, String orderId, double refundMoney, String orderNO) throws IOException {

        OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderId);
        PayPalClient payPalClient = new PayPalClient();
        HttpResponse<Order> ordersGetResponse = null;
        try {
            ordersGetResponse = payPalClient.client(mode, clientId, clientSecret).execute(ordersGetRequest);
        } catch (Exception e) {
            try {
                log.error("第1次调用paypal订单查询失败");
                ordersGetResponse = payPalClient.client(mode, clientId, clientSecret).execute(ordersGetRequest);
            } catch (Exception e2) {
                try {
                    log.error("第2次调用paypal订单查询失败");
                    ordersGetResponse = payPalClient.client(mode, clientId, clientSecret).execute(ordersGetRequest);
                } catch (Exception e3) {
                    log.error("第3次调用paypal订单查询失败，失败原因：{}" + e3.getMessage());
                }
            }
        }
        String captureId = ordersGetResponse.result().purchaseUnits().get(0).payments().captures().get(0).id();
        CapturesRefundRequest request = new CapturesRefundRequest(captureId);
        request.prefer("return=representation");
        request.requestBody(buildRequestBody(refundMoney, orderNO));
        HttpResponse<Refund> response = null;
        try {
            response = payPalClient.client(mode, clientId, clientSecret).execute(request);
        } catch (IOException e) {
            try {
                log.error("第1次调用paypal退款申请失败");
                response = payPalClient.client(mode, clientId, clientSecret).execute(request);
            } catch (Exception e1) {
                try {
                    log.error("第2次调用paypal退款申请失败");
                    response = payPalClient.client(mode, clientId, clientSecret).execute(request);
                } catch (Exception e2) {
                    log.error("第3次调用paypal退款申请失败，失败原因 {}" + e2.getMessage());
                }
            }
        }
        log.info(String.format("Status Code = {}, Status = {}, RefundID = {}", response.statusCode(), response.result().status(), response.result().id()));
        if ("COMPLETED".equals(response.result().status())) {
            //进行数据库操作，修改状态为已退款（配合回调和退款查询确定退款成功）
            log.info("退款成功");
            return true;
        }
    /*for (com.paypal.payments.LinkDescription link : response.result().links()) {
      log.info("Links-{}: {}    \tCall Type: {}", link.rel(), link.href(), link.method());
    }
    String json = new JSONObject(new Json().serialize(response.result())).toString(4);
    log.info("refundOrder response body: {}", json);*/
        return false;

    }

}
